using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System;

using myBase;

class Program {
    static void Main(){
        Application.Run(new HistMainForm());
    }
}

class HistMainForm : BaseForm{
    private histDialogForm d;
    public HistMainForm(){
        var btn = new Button();
        btn.Parent = this;
        btn.Name = "histogram";
        btn.Text = "绘制直方图";
        btn.Location = new Point(37,200);
        btn.Click += new EventHandler(hist_Click);
    }

    private void hist_Click(object sender,EventArgs e){
        if(curBitmap != null){
            d = new histDialogForm(curBitmap);
            d.ShowDialog();
        }
    }
}

class histDialogForm : Form {
    private Bitmap bmpHist;
    private int[] countPixel;
    private int maxPixel;

    public histDialogForm(Bitmap bmp){
        bmpHist = bmp;
        countPixel = new int[256];

        var btn = new Button();
        btn.Parent = this;
        btn.Name = "close";
        btn.Text = "关闭";
        btn.Location = new Point(252,265);
        btn.Click += new EventHandler(close_click);
    }

    private void close_click(object sender,EventArgs e){
        this.Close();
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        // 读取像素数据
        var rect = new Rectangle(0,0,bmpHist.Width,bmpHist.Height);
        BitmapData bmpData = bmpHist.LockBits(
            rect,
            ImageLockMode.ReadWrite,
            bmpHist.PixelFormat
        );
        IntPtr ptr = bmpData.Scan0;
        int bytes = bmpHist.Width * bmpHist.Height;
        byte[] grayValues = new byte[bytes];
        Marshal.Copy(ptr,grayValues,0,bytes);

        // 遍历像素数据
        byte temp = 0;
        maxPixel = 0;
        Array.Clear(countPixel,0,256);
        for(int i =0;i<bytes;i++){
            temp = grayValues[i];
            countPixel[temp] = countPixel[temp]  + 1;
            if(countPixel[temp] > maxPixel){
                maxPixel = countPixel[temp];
            }
        }

        // 释放内存
        Marshal.Copy(grayValues,0,ptr,bytes);
        bmpHist.UnlockBits(bmpData);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        var g = e.Graphics;
        Pen curPen = new Pen(Brushes.Black,1);

        g.DrawLine(curPen,50,240,320,240);
        g.DrawLine(curPen,50,240,50,30);

        g.DrawLine(curPen,100,240,100,242);
        g.DrawLine(curPen,150,240,150,242);
        g.DrawLine(curPen,200,240,200,242);
        g.DrawLine(curPen,250,240,250,242);
        g.DrawLine(curPen,300,240,300,242);

        g.DrawString("0",new Font("New Timer",8),Brushes.Black,new PointF(46,242));
        g.DrawString("50",new Font("New Timer",8),Brushes.Black,new PointF(92,242));
        g.DrawString("100",new Font("New Timer",8),Brushes.Black,new PointF(139,242));
        g.DrawString("150",new Font("New Timer",8),Brushes.Black,new PointF(189,242));
        g.DrawString("200",new Font("New Timer",8),Brushes.Black,new PointF(239,242));
        g.DrawString("250",new Font("New Timer",8),Brushes.Black,new PointF(289,242));

        g.DrawLine(curPen,48,40,50,40);
        g.DrawString("0",new Font("New Timer",8),Brushes.Black,new PointF(34,234));
        g.DrawString(maxPixel.ToString(),new Font("New Timer",8),Brushes.Black,new PointF(18,34));

        double temp = 0;
        for(int i = 0;i < 256;i++){
            temp = 200.0 * countPixel[i] / maxPixel;
            g.DrawLine(curPen,50+i,240,50+i,(240-(int)temp));
        }
        curPen.Dispose();
    }
}
